package com.cskaoyan.javase.oop2._2polymorphic._3exercise;
/**
 * 多态场景下方法调用怎么去看?
 *      方法调用,编译时看左边,运行时看右边
 * 编译时看左边,意味着只能够访问引用类型中的方法:
 *      如果引用是一个父类类型,那么在编译时就无法去查看子类方法,只能看父类方法
 *      如果引用是一个子类类型,那么在编译时,不仅要看子类方法,还要看父类方法
 *
 * 除此之外,方法调用还需要考虑就近原则
 *
 *
 * @since 11:36
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo2 {
    public static void main(String[] args) {
        A a1 = new A();
        A a2 = new B();
        B b = new B();
        C c = new C();
        D d = new D();
        // a1是父类引用指向父类对象,全程和子类没有关系
        System.out.println("1--" + a1.show(b)); //AA
        System.out.println("2--" + a1.show(c)); //AA
        System.out.println("3--" + a1.show(d)); //AD

        // a2是父类引用指向子类对象,编译时只和父类类型有关,但运行调用还要看子类是否重写该方法
        System.out.println("4--" + a2.show(b)); //BA
        System.out.println("5--" + a2.show(c)); //BA
        System.out.println("6--" + a2.show(d)); //AD


        // b是子类引用指向子类对象,编译时需要看父类和子类,调用结果也一样,需要体现出子类的行为(当然,如果子类没有这个方法,要体现出父类行为)
        System.out.println("7--" + b.show(b)); //BB
        System.out.println("8--" + b.show(c)); //BB
        System.out.println("9--" + b.show(d)); //AD
    }
}

class A {
    public String show(D obj) {
        return ("A and D");
    }

    public String show(A obj) {
        return ("A and A");
    }
}

class B extends A {
    // 该方法是B类中子类独有的方法
    public String show(B obj) {
        return ("B and B");
    }

    // 该方法是B类中重写父类A中的方法
    @Override
    public String show(A obj) {
        return ("B and A");
    }
}

class C extends B {
}

class D extends B {
}